React 원리 : VDOM은 빨라서 쓰는 것이 아니다

React의 VDOM은 왜 등장했고, 정말 빠른가?

리액트를 공부할 때 가장 먼저 마주치는 개념이 Virtual DOM이다. 흔히 “VDOM이 빠르다”라고 알고 있지만, VDOM은 실제 DOM보다 빠르기 때문에 존재하는 게 아니라, DOM을 직접 다루는 방식보다 안정적이고 예측 가능한 렌더링 모델을 제공하기 위해 등장했다.


가장 큰 이유는 DOM 조작이 생각보다 무겁기 때문이다. 실제 DOM을 건드리면 브라우저는 레이아웃 재계산, 스타일 재계산, 페인트, 컴포지팅과 같은 렌더링 파이프라인을 다시 실행해야 한다. 이 과정은 비용이 크고, 빈번하게 실행되면 성능 저하로 이어진다. VDOM은 이런 비싼 DOM 접근을 최소화하기 위해 만들어진 일종의 버퍼다. 브라우저 렌더링 비용이 워낙 크기 때문에, 여러 상태 변경이 일어나면 이것을 배치로 처리하여 “비싼 DOM 접근을 줄이는 전략”이 효율적이기 때문이다.


React는 렌더링할 때 전체 UI를 다시 계산한 뒤, 그 결과를 VDOM이라는 JS 객체 구조로 만든다. 그리고 이전 렌더 결과와 비교(diff)하여 변경된 부분만 실제 DOM에 반영한다. 따라서 개발자는 React에선, 실제 DOM 조작 없이, “UI = 상태의 함수”처럼 선언적으로 코드를 작성할 수 있고, React는 그 결과를 안정적으로 최소 DOM 변경으로 이어지게 한다.


이때 중요한 점은 VDOM이 DOM보다 빠른 것이 아니라는 것이다. VDOM 자체도 생성·비교 비용이 있다. 순수 퍼포먼스 관점에서 보면 “VDOM 생성 → diff → 실제 DOM 패치”라는 과정이 DOM 직접 조작보다 더 느릴 수도 있다.


VDOM을 쓰지 않는 Svelte, Vue

최근 프레임워크들은 VDOM을 아예 사용하지 않거나, 제한적으로만 사용한다. 대표적인 경우가 Svelte, Vue3다. Svelte는 실제 DOM을 직접 조작함에도 불구하고 여러 벤치마크에서 React보다 빠른 렌더 성능을 보인다는 것이다.


Svelte는 컴파일 타임 프레임워크다. 템플릿을 빌드할 때 “어떤 상태가 어떤 DOM을 어떻게 바꾸는지”를 정확히 계산해서, 실행 시에는 그 DOM만 직접 패치하는 코드를 만들어낸다. 즉, VDOM diff 과정 자체가 존재하지 않는다.


Vue 3Proxy 기반 반응성으로 “어떤 값이 바뀌었는지”를 알고 있으며, 그 값이 사용된 컴포넌트만 다시 렌더해 VDOM 패치를 수행한다. React처럼 상위 컴포넌트가 렌더되면 하위 컴포넌트가 전부 다시 렌더되는 구조가 아니다.


이런 구조 덕분에 Svelte나 Vue는 “정확히 어떤 DOM이 바뀌는지 알고 있는 상황”에서는 React보다 훨씬 빠르다. 리스트 렌더링, 단순한 UI, 변경 지점이 명확한 구조에서는 특히 차이가 크다. React는 모든 렌더마다 전체 컴포넌트를 실행해 VDOM을 구성해야 하고, 그 후에 diff를 거쳐야 하기 때문이다.


그렇다면 VDOM 없는 프레임워크는 항상 빠를까?

그렇지도 않다. VDOM 없는 Reactivity 기반 프레임워크도 특정 상황에서는 오히려 React보다 느려질 수 있다.

이 시스템들은 “상태 → DOM” 매핑을 알고 있어야 빠르다. 하지만 UI 구조가 복잡해지고 상태 의존성이 수천~수만 개로 늘어나면, 반응성 그래프를 추적하고 유지하는 비용이 커진다. 변경된 상태가 영향을 미치는 모든 구독자(컴포넌트 또는 DOM 패치 함수)를 호출해야 하기 때문이다. 이런 경우에는 Svelte가 오히려 더 많은 연산을 수행하게 된다.


동적으로 DOM 구조가 자주 변하는 UI 역시 부담이 된다. Svelte는 컴파일 타임에 DOM 구조를 컴파일하기 때문에 구조가 매우 자주 바뀌거나 예측 불가능하면 관리 비용이 커진다. 대규모 대시보드나 deeply nested UI처럼 구조적 복잡성이 높은 화면에서는 React의 “전체 렌더 → diff” 모델이 오히려 더 안정적일 수 있다.


결론

React VDOM은 DOM보다 빠르기 때문에 사용하는 것이 아니라, DOM을 직접 다루는 복잡성을 추상화하고 배치 처리를 통해 DOM 접근을 최소화하여 무거운 연산의 횟수를 줄이기 위해 존재한다.


반면 SvelteVue는 변경 지점을 더 정확히 알고 있기 때문에 초기 렌더나 단순한 UI에서는 React보다 훨씬 빠르게 동작한다. 그러나 상태 의존성이 복잡하게 얽힌 대규모 UI에서는 반응성 시스템의 관리 비용이 커져 React의 접근 방식이 더 유리한 경우도 존재한다.


즉, 성능만의 문제라기보다 “어떤 UI 구조인지”, “어떤 상태 관리 구조인지”, “어떤 개발 경험을 원하는지”에 따라 선택이 달라진다. React는 직접 DOM 접근을 추상화하는 컨셉이며, Svelte와 Vue는 반응성을 유지하여 변하는 부분을 명시하는 컨셉이다. 각각이 지향하는 철학이 다르기 때문에, 어떤 것이 더 우월하다고 단정하기 어렵다. 다만 단순한 속도만 놓고 보면 VDOM이 없는 구조가 대부분 더 빠른 것만은 분명하다.